#include<iostream>
using namespace std;

class Point {
    private:
        float x,y;
    public:
        Point(float a = 0,float b = 0):x(a),y(b) {
            cout << "initializing x = " << x << ",y = " << y << endl;
        }
        Point(const Point &);
        float getX() {
            return x;
        }

        float getY() {
            return y;
        }

        void show() {
            cout << "show ... this = "<< this <<",x = " << x << ",y = " << y << endl;
        }

        ~Point() {
            cout << "destructor ... this = " <<this << ",x = " << x << ",y = " << y << endl;
        }
};

Point::Point(const Point &p) {
    x = p.x;
    y = p.y;
    cout <<  "copy constructor ... x = " << x << ",y = " << y << endl;
}

void display(Point p) {
    cout << "display fun p 'Address = " << &p << endl;
    p.show();
}

void displayR(Point &p) {
    cout << "displayR fun p'Address = " << &p << endl;
    p.show();
}

Point fun() {
    Point A(1,2);
    cout << "fun A'Address = " << &A << endl;
    return A;
}
/**
 * warning:
 * reference to stack memory associated with variable
 * 'A' returned.
 */
Point& funR() {
    Point A(8,9);
    cout << "funR A'Address = " << &A << endl;
    return A;
}

//#define DEBUG
//#define D

int main() {
#ifdef DEBUG
    Point A(3,4);
    Point B(A);
    Point C(5,6);
    cout << "call display(C)" << endl;
    cout << "C'Address = " << &C << endl;
    display(C);
    cout << "call displayR(C)" << endl;
    displayR(C);

    cout << "call fun" << endl;
    C = fun();
    cout << "call displayR(C)" << endl;
    displayR(C);
    cout << "ready to Point D" << endl;
#endif
#ifdef D
    Point D;
    D.show();
    D = fun();
    D.show();
#endif
    Point E = fun();
    E.show();
    Point F = funR();
    F.show();
    /*
    cout << "call displayR(D)" << endl;
    displayR(D);
    */
    cout << "main begin to exit" << endl;
    return 0;
}
